define(function(require, exports, module) {
    'use strict';

    var me = {};

    var isEditMode = (SESSION.prj === 'canvas');

    var _rk;
    me.setRk = function(rk) {
        _rk = rk;
    };

    var GLOBAL_JSON = {
        config: {},
        layout: {},
        data: {
            common: {}
        }
    };

    var OriginalFormJson;//存储server端来的原始formjson

    { //get global stuff
        me.getCommonData = function() {
            return $.extend(true, {}, GLOBAL_JSON.data.common);
        };
        me.getWidgetData = function(id) {
            if (_rk.formMgr.getWidgetInfo(id)) {
                return GLOBAL_JSON.data[id];
            }
        };
    }

    var biz_prefix;
    (function(url) {
        var arr = (url).match(/[\w_]+\.action/ig);
        if (arr.length > 0) {
            biz_prefix = arr[0].replace('.action', '')
        }
    })(window.location.href);

    if (biz_prefix.indexOf('_detail') < 0) biz_prefix += '_detail';
    var layout_url = '/json/crm_' + biz_prefix + '/load-layout.action';//'/static/source/designer/w-load-layout.action.json'
    var pagedata_url = '/json/crm_' + biz_prefix + '/load-pagedata.action';
    var compdata_url = '/json/crm_' + biz_prefix + '/load-compdata.action';
    var saveconfig_url = '/json/crm_' + biz_prefix + '/user-config.action'; //回存用户数据

    var layout_edit_url = '/admin/designer/openedit-detaillayout.action';//?entityId=355102&layoutId=227216；编辑 既有的DetailLayout

    // crm_customize_detail/load-layout
    // crm_customize_detail/load-pagedata
    // crm_customize_detail/load-compdata

    var mockdata_url = '/static/source/platform/manager/mock/load-pagedata.action.json';
    //241305(有商机的客户)
    var entityId, groupId;

    { //Requst init-data
        var getSafeJson = function(json) { //干掉恶意html字符
            return escapeNode(json)
        };
        var escapeNode = function(node, nodeKey) {
            if ($.isArray(node)) {
                for (var i = 0, len = node.length; i < len; i++) {
                    node[i] = escapeNode(node[i]);
                }
            } else if (typeof node == 'object') {
                for (var key in node) {
                    node[key] = escapeNode(node[key], key);
                }
            } else {
                node = (nodeKey == 'label' || nodeKey == 'name') ? lightEscape(node) : node;
            }
            return node;
        };
        var lightEscape = function(s) { //不需要过度替代，仅破坏掉<>字符即可
            var type = typeof s;
            if (!s || type != 'string') return s;
            return (s + '')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
        };
        me.getOriginalFormJson = function(){
            return OriginalFormJson;
        };
        me.loadLayout = function(succFn) {
            if(isEditMode){
                var isMondifyNotCreate = !!$.query('layoutId');//true是编辑模式，false是新建模式
                me.loadLayout1(succFn);
            }else{
                me.loadLayout2(succFn);
            }
        };
        //作为设计器canvas时
        me.loadLayout1 = function(succFn) {
            var xhr = $.getJSON(layout_edit_url, {
                entityId: $.query('entityId'),
                layoutId: $.query('layoutId')
            });
            xhr.done(function(json) {
                    if (json.status && json.status > 300000) {
                        //没有权限等系统错误
                        _rk.formMgr.handleErrorStatus(json.status);
                        return;
                    }
                    if(!_rk.isIE && parent.$ && parent.$.query('test') && localStorage.getItem('SAVEDFORM')){
                        json = JSON.parse(localStorage.getItem('SAVEDFORM'));  
                    }
                    json = getSafeJson(json)
                    json = currectBetaJson(json);
                    OriginalFormJson = $.extend(true, {}, json);//缓存
                    _rk.runDesignerMethod('designer.canvas.handleOnDataLoad', OriginalFormJson);
                    (succFn)(json);
                })
                .fail(function(jqxhr, textStatus, error) {
                    var err = textStatus + ", " + error;
                    _rk.noticeError('请求页面结构数据错误');
                })
                .always(function() {});
        };
        //作为正常的详情页时
        me.loadLayout2 = function(succFn) {
            if (window.ttt0) { //性能
                var cost0 = (window.ttt0 - seajs.data.time0);
                _rk.formMgr._cost_seajs = cost0;
                // console.log('%c性能监测（JS）：seajs加载：' + cost0 + 'ms', "color:red;background-color:#ffffcc;")
            }
            //初始化id
            entityId = $.query('id');
            groupId = $.query('gid');
            _rk.crm.setDetailId(entityId);
            _rk.crm.setGroupId(groupId);

            var query = _rk.getUrlParam('belongId') ? {
                id: entityId,
                belongId: _rk.getUrlParam('belongId')
            } : {
                id: entityId
            };
            if ($.query('gid')) {
                query.gid = $.query('gid');
                delete query.id;
            }
            //query = {id: 301097, belongId:347013}

            var xhr = $.getJSON(layout_url, query);
            xhr.done(function(json) {
                    if (json.status && json.status > 300000) {
                        //没有权限等系统错误
                        _rk.formMgr.handleErrorStatus(json.status);
                        return;
                    }
                    removeNoPermissions(json.layout, json.widgets);
                    //json = require('./mock/layout_config_customize.json')
                    json = getSafeJson(json)
                    json = currectBetaJson(json);
                    OriginalFormJson = $.extend(true, {}, json);//缓存
                    if (json.config) {
                        for (var key in json.config) {
                            if (typeof json.config[key] != 'object') {
                                GLOBAL_JSON.config[key] = json.config[key];
                            }
                        }
                    }
                    if (json.data && json.data.common) {
                        $.extend(true, GLOBAL_JSON.data.common, json.data.common);
                        _rk.crm.setGroupId(json.data.common.groupId);
                        _rk.crm.setBelongId(json.data.common.belongId);

                        _rk.crm.setDetailId(json.data.common.id);

                        if (json.data.common.belongLabel) _rk.setTitle(json.data.common.belongLabel);
                    }
                    (succFn)(json);
                })
                .fail(function(jqxhr, textStatus, error) {
                    var err = textStatus + ", " + error;
                    _rk.noticeError('请求页面结构数据错误');
                })
                .always(function() {});
        };
        var getBetaCurrectId = function(){
            return '9'+Math.floor(Math.random()*100000)+'9';
        };
        var currectBetaJson = function(json){
            var layout = json.config.layout;
            var node13, node14, nodeOppoProgress;
            var nodeTabs = {};
            _rk.formMgr.foreachChildren(layout, function(info){
                if(true && info && info.uuid === '1' && json.config.widgets['1'].widgetType === 'xsyOpportunityDetail') {
                    //var livingList = _rk.formMgr.getLivingChildrenList('111');
                    if(info.children && $.isArray(info.children.body) && info.children.body.length > 1){
                        for(var i=0,len=info.children.body.length;i<len;i++){
                            var child = info.children.body[i];
                            if(json.config.widgets[child.uuid].widgetType === 'xsyOpportunityProgress'){
                                nodeOppoProgress = child;
                                var oldProgressid = nodeOppoProgress.uuid;
                                var newdivid = getBetaCurrectId();
                                info.children.body[i] = {
                                    'uuid': newdivid,
                                    'children': {
                                        'list': [{'uuid':  oldProgressid}]
                                    }
                                };
                                json.config.widgets[newdivid] = {
                                    'uuid': newdivid,
                                    'widgetType': 'xsyHorizontalLayout'
                                }

                            }
                        }
                    }
                }
                if(true && info && info.uuid === '13' && json.config.widgets['13'].widgetType === 'xsyHorizontalLayout' && $.isArray(info.children)) node13 = info;
                if(true && info && info.uuid === '14' && json.config.widgets['14'].widgetType === 'xsyVerticalLayout' && $.isArray(info.children)) node14 = info;
                if(true && json.config.widgets[info.uuid] && json.config.widgets[info.uuid].widgetType === 'xsyTab'){
                    nodeTabs[info.uuid] = info;
                }
            });
            //改动之处：
            //  一、id为13的节点（xsyHorizontalLayout），其子不应记录为数组，而需打散到left和right中
            //  二、id为14的节点删除，其子并到13的right中
            //  三、tab的title收进buttons属性中，去除子控件中的title属性

            {//对tab的升级
                for(var key in nodeTabs){//遍历所有tab看是否有问题
                    var tab = nodeTabs[key];
                    if(tab.children){
                    for(var i=0,len=tab.children.length;i<len;i++){
                        var obj = $.extend(true, {}, tab.children[i]);
                        var childid = obj.uuid;
                        var childinfo = json.config.widgets[childid];
                        if(childinfo && childinfo.widgetType !== 'xsyDiv'){//tab的孩子仅接收xsyDiv，否则是旧数据，需包一层xsyDiv
                            var title = childinfo.attributes.title;
                            childinfo.attributes.title = null;
                            var newid = getBetaCurrectId();
                            tab.children[i] = {
                                'uuid': newid,
                                'children': [obj]
                            };
                            //console.log(title)
                            json.config.widgets[newid] = {
                                attributes: {
                                    title: title
                                },
                                uuid: newid,
                                widgetType: "xsyDiv",
                            }
                        }
                    }
                    }else{
                        tab.children = [];
                    }
                }
                _rk.formMgr.foreachChildren(layout, function(info){
                    if(nodeTabs[info.uuid]) {
                        info = nodeTabs[info.uuid];
                    };
                });
            }
            //对node13和14的升级
            if(node13){
                var children = $.extend(true, {}, node13.children);
                node13.children = null;
                node13.children = {
                    'left': [children[0]],
                    'right': [children[1]]
                };
                if(node14)
                if(node13.children.right && json.config.widgets['14'].widgetType == 'xsyVerticalLayout'){
                    var children14 = $.extend(true, [], node13.children.right[0].children);//删除id为14的节点，其子挂接到node13的right上
                    node13.children.right = children14;
                    delete json.config.widgets['14'];
                }
            }
            return json;
        };
        var removeNoPermissions = function(layout, widgets) {
            //TODO，实现这个方法，在这里砍掉无权限的控件
        };
    }

    { //Request widgets-data, ALL-IN-ONE
        var initDataIsDone = false; //是否已请求初始数据，如果未请求，则应当请求load-pagedata，否则应请求load-compdata
        var firstLoadIsDone = false; //第一次加载完成
        var requestUids = {};
        var loaddata_timer;
        me.firstLoadIsDone = function() {
            return firstLoadIsDone;
        };
        me.loadData = function(uuid, params, successFn, errorFn) {
            if(isEditMode){
                var isMondifyNotCreate = !!$.query('layoutId');//true是编辑模式，false是新建模式
                me.loadData1(uuid, params, successFn, errorFn);
            }else{
                me.loadData2(uuid, params, successFn, errorFn);
            }
        };
        //作为设计器canvas时
        me.loadData1 = function(uuid, params, successFn, errorFn) {
            //console.log('load fake data', uuid)
        };
        //作为详情页时
        me.loadData2 = function(uuid, params, successFn, errorFn) {
            if(isEditMode)return;
            if (!$.isNumeric(uuid)) return; //非后台控件
            var reqObj = {
                uuid: uuid,
                params: params,
                successFn: successFn,
                errorFn: errorFn
            };
            var info = _rk.formMgr.getWidgetInfo(uuid);
            if (info && (/(Header)$/g).test(info.widgetType)) {
                var o = {};
                o[uuid] = [reqObj];
                _doLoadData(o);
            } else {
                if (!$.isArray(requestUids[uuid])) {
                    requestUids[uuid] = [];
                }
                requestUids[uuid].push(reqObj);
                window.clearTimeout(loaddata_timer);
                loaddata_timer = window.setTimeout(function() {
                    if (window.ttt0) { //性能
                        window.ttt3 = new Date();
                        var cost = (window.ttt3 - window.ttt2);
                        _rk.formMgr._cost_widget += cost;
                        // console.log('%c性能监测（JS）：请求间隙时间：' + cost + 'ms', "color:red;background-color:#ffffcc;")
                    }
                    _doLoadData();
                }, 1);
            }
        };
        var _doLoadData = function(requestUids2) {
            var params = {};
            var configs = {};
            var alone = !!requestUids2;
            requestUids2 = alone ? requestUids2 : requestUids;
            for (var uuid in requestUids2) {
                for (var i = 0, len = requestUids2[uuid].length; i < len; i++) {
                    var unit = requestUids2[uuid][i];
                    if ((params[uuid] && (typeof params[uuid].noLoadList == 'undefined')) && unit.params.noLoadList) {
                        delete unit.params.noLoadList; //noLoadList这个属性是只加载部分数据，但如果有多个控件请求该数据的话，以请求全的为准
                    }
                    params[uuid] = $.extend(params[uuid], unit.params);

                    var widgetInfo = _rk.formMgr.getWidgetInfo(uuid);
                    var config = {};
                    for (var k in widgetInfo) {
                        if (!$.isArray(widgetInfo[k])) config[k] = widgetInfo[k];
                    }
                    configs[uuid] = config;
                }
            }
            _rk.formMgr.broadcast('sysBeforeLoadData');
            if (!alone) {
                requestUids = {}; //即刻清空，因为可能在请求期间，仍有控件在申请数据
            }
            var url = !initDataIsDone ? pagedata_url : compdata_url;
            initDataIsDone = true;

            var param = {
                query: JSON.stringify(params),
                config: JSON.stringify(configs),
                belongId: _rk.crm.getBelongId()
            };
            if ($.query('gid')) param.gid = groupId;
            if ($.query('id')) param.id = entityId;

            var xhr = $.post(url, param);
            xhr.done(function(json) {
                    //json = require('./mock/load-pagedata2.action.json')
                    if (!json) _rk.noticeError('数据请求出错，后台数据错误')
                    // json = getSafeJson(json)
                    if (window.ttt0) { //性能
                        window.ttt4 = new Date();
                        var cost43 = (window.ttt4 - window.ttt3);
                        _rk.formMgr._cost_loaddata += cost43;
                        // console.log('%c性能监测（后端）：loaddata请求：' + cost43 + 'ms', "color:red;background-color:#ffffcc;")
                    }
                    json = (json && json.data) ? json : {
                        'data': {
                            'common': {}
                        }
                    };
                    if (!json.data.common) json.data.common = {};
                    if (json.data.common.groupId) _rk.crm.setGroupId(json.data.common.groupId);
                    _updateGlobalData(json);
                    for (var uuid in requestUids2) {
                        var winfo = _rk.formMgr.getWidgetInfo(uuid);
                        var array = requestUids2[uuid];
                        for (var i = 0, len = array.length; i < len; i++) {
                            var unit = array[i];
                            if (unit.successFn) {
                                var result = {
                                    uuid: uuid,
                                    common: $.extend(true, {}, GLOBAL_JSON.data.common),
                                    self: json.data[uuid] ? json.data[uuid] : {}
                                };

                                { //调试代码，开始
                                    if (_rk.getUrlParam('dbg'))
                                        if (!initDataIsDone && result.self && result.self.entityData && result.self.entityData.length > 0) {
                                            var ed = $.extend(true, {}, result.self.entityData[0])
                                            for (var i = 0; i < 10; i++) {
                                                result.self.entityData.push(ed)
                                            }
                                        }
                                } //调试代码，结束。
                                unit.successFn(result);
                                try {} catch (e) {
                                    // console.log('%c数据绑定错误：' + winfo.uuid + ',' + winfo.widgetType + ',"' + e.message + '"', "color:black;background-color:red;")
                                    console.error(e)
                                }
                            }
                        }
                    }

                    _rk.formMgr.broadcast('sysAfterLoadData');
                    if (window.ttt0) { //性能
                        window.ttt5 = new Date();
                        var cost5_4 = (window.ttt5 - window.ttt4);
                        _rk.formMgr._cost_widget += cost5_4;
                        // console.log('%c性能监测（JS）：数据绑定：' + cost5_4 + 'ms', "color:red;background-color:#ffffcc;")
                        // console.log('-----------------------')
                        // console.log('%c统计：  页面总耗时' + (window.ttt5 - seajs.data.time0) + 'ms', "color:red;background-color:#ffffcc;")
                        // console.log('%c     seajs：' + _rk.formMgr._cost_seajs + 'ms', "color:red;background-color:#ffffcc;")
                        // console.log('%c     平台：' + (window.ttt5 - window.ttt0) + 'ms', "color:red;background-color:#ffffcc;")
                        // console.log('%c        平台js：' + _rk.formMgr._cost_widget + 'ms', "color:red;background-color:#ffffcc;")
                        // console.log('%c        平台后端：' + _rk.formMgr._cost_loaddata + 'ms', "color:red;background-color:#ffffcc;")
                        delete window.ttt0;
                    }
                })
                .fail(function(jqxhr, textStatus, error) {
                    _rk.noticeError('数据请求出错')
                })
                .always(function() {
                    firstLoadIsDone = true;
                });
        };
        var _updateGlobalData = function(json) {
            $.extend(true, GLOBAL_JSON.data, json.data); //合并到GLOBAL_JSON中
            //loadDataToVm();
        };
    } { //回存控件状态
        var saveattributesCache = {};
        var saveattributes_timer;
        me.saveAttributes = function(uid, attributes) {
            if (!saveattributesCache[uid]) saveattributesCache[uid] = {
                attributes: {}
            };
            saveattributesCache[uid].attributes = $.extend(true, saveattributesCache[uid].attributes, attributes);

            window.clearTimeout(saveattributes_timer);
            saveattributes_timer = window.setTimeout(function() {
                _doSaveAttributes();
            }, 200 * 1);
        };
        var _doSaveAttributes = function() {
            var url = saveconfig_url;
            var savejson = {};
            for (var key in GLOBAL_JSON.config) {
                savejson[key] = GLOBAL_JSON.config[key];
            }
            savejson.widgets = saveattributesCache;
            var xhr = $.post(url, {
                config: JSON.stringify(savejson)
            });
            xhr.done(function(json) {
                saveattributesCache = {};
            });
        };
    } { //Vue辅助  
        var GLOBAL_VM;

        var loadDataToVm = function() {
            var gdata = GLOBAL_JSON.data;

            if (!GLOBAL_VM) {
                var gdataforvue = {};
                gdataforvue = $.extend(true, gdataforvue, gdata);
                for (var k in gdataforvue) {
                    gdataforvue['vue_' + k] = gdataforvue[k]; //这一步是为了绕过vue不支持key为数字的问题
                    delete gdataforvue[k];
                }
                GLOBAL_VM = new Vue({
                    data: gdataforvue
                });
            }

            //监控大字段
            for (var appKey in gdataforvue) {
                // console.log('watch', appKey)
                appKey = appKey;
                GLOBAL_VM.$watch(appKey, function(newVal, oldVal) {
                    handleDataUpdate(appKey, newVal, oldVal);
                }, {
                    deep: true //deep watch
                })
            }
        };
        var handleDataUpdate = function(appKey, newVal, oldVal) {
            // console.log('new:', newVal, 'old:', oldVal)
            _rk.formMgr.broadcast(appKey);
        };

        me.getVM = function() {
            return GLOBAL_VM;
        };
        me.updateVm = function(appKey, newJson) {
            //GLOBAL_VM.$data[appKey] = newJson;
            GLOBAL_VM.$set(appKey, newJson)
        };
    } { //权限合并
        me.mergePermission = function(serverP, myP) { //将自己权限和server权限合并，自己的权限优先级高于server的
            //serverP:
            //1.查看列表（l）亦即是否有权限看；2.创建（c）；3.修改（u）；4.删除（d）；5.查看（v）；6.导入（i）；7.导出（e）；8.转换（t）；10.菜单（m）
            if (typeof myP == 'undefined' || !myP) {
                myP = {};
                myP['create'] = (typeof serverP.c == 'undefined' ? true : (serverP.c == 1 ? true : false));
                myP['update'] = (typeof serverP.u == 'undefined' ? true : (serverP.u == 1 ? true : false));
                myP['delete'] = (typeof serverP.d == 'undefined' ? true : (serverP.d == 1 ? true : false));
                myP['view'] = (typeof serverP.v == 'undefined' ? true : (serverP.v == 1 ? true : false));
                myP['import'] = (typeof serverP.i == 'undefined' ? true : (serverP.i == 1 ? true : false));
                myP['export'] = (typeof serverP.e == 'undefined' ? true : (serverP.e == 1 ? true : false));
                myP['transfer'] = (typeof serverP.t == 'undefined' ? true : (serverP.t == 1 ? true : false));
                myP['menu'] = (typeof serverP.m == 'undefined' ? true : (serverP.m == 1 ? true : false));
            } else {
                if (typeof serverP == 'undefined' || !serverP) {
                    myP._showmenu = _showMenuOrNot(myP);
                    return myP;
                } else {
                    if (typeof myP['create'] == 'undefined' && typeof serverP.c != 'undefined') myP['create'] = (serverP.c == 1 ? true : false);
                    if (typeof myP['update'] == 'undefined' && typeof serverP.u != 'undefined') myP['update'] = (serverP.u == 1 ? true : false);
                    if (typeof myP['delete'] == 'undefined' && typeof serverP.d != 'undefined') myP['delete'] = (serverP.d == 1 ? true : false);
                    if (typeof myP['view'] == 'undefined' && typeof serverP.v != 'undefined') myP['view'] = (serverP.v == 1 ? true : false);
                    if (typeof myP['import'] == 'undefined' && typeof serverP.i != 'undefined') myP['import'] = (serverP.i == 1 ? true : false);
                    if (typeof myP['export'] == 'undefined' && typeof serverP.e != 'undefined') myP['export'] = (serverP.e == 1 ? true : false);
                    if (typeof myP['transfer'] == 'undefined' && typeof serverP.t != 'undefined') myP['transfer'] = (serverP.t == 1 ? true : false);
                    if (typeof myP['menu'] == 'undefined' && typeof serverP.m != 'undefined') myP['menu'] = (serverP.m == 1 ? true : false);
                }
            }
            myP._showmenu = _showMenuOrNot(myP);
            return myP;
        };
        me.getOpMenuItems = function(permissions){

            var menuItems = new Array();
            if (permissions['delete'] === true) menuItems.push({act:'delete', label: _rk.i18n('CRM_CORE_DELETE')})
            if (permissions['remove'] === true) menuItems.push({act:'remove', label : _rk.i18n('CRM_CORE_REMOVE')})
            if (permissions['transfer'] === true) menuItems.push({act: 'transfer', label : _rk.i18n('CRM_CORE_TRANSFER')})
            if(permissions['setMain'] === true) menuItems.push({act:'setMain', label : _rk.i18n('OPPORTUNITY_SET_MAIN_CONTACT', SESSION.keywords.contact)})

            return menuItems;
        };
        var _showMenuOrNot = function(permissions) { //是否需要显示小菜单
            var menuItems = me.getOpMenuItems(permissions);
            if( menuItems && menuItems.length > 0){
                return true;
            }else{
                return false;
            }
        }
    }

    module.exports = me;
});
